package model;

import java.util.ArrayList;

//hangya osztaly game objectbol szarmaztatva
public abstract class Ant extends GameObject{ 

	protected double dir_x;
	protected double dir_y;
	protected double dir;
	protected int capacity;
	protected int foodcarried;
	protected boolean goinghome;
	protected MapElement anthill;
	protected double speed;
	protected boolean isAlive=true;
	protected Ant follower;
	protected int movecounter=0;
	
	//alapkonstuktor 
	public Ant(Game currgame){		
		super(currgame,"Ant");
		for(MapElement m : currgame.currentMap.mapelements){
			if (m.type.equals("anthill")) anthill=m;
		}
		loc_x=anthill.loc_x;
		loc_y=anthill.loc_y;
		dir=Math.random()*360;
		dir_x=Math.sin(dir);
		dir_y=Math.cos(dir);
		double lenght=Math.sqrt(dir_x*dir_x+dir_y*dir_y);
		dir_x/=lenght;
		dir_y/=lenght;
		follower=this;
	}
	
	//hangyak move fuggvenye
	public void move(){	
				movecounter++;
				//szagnyomot hagy a hangya:
				//uj szagnyom letrehozasa a hangya aktualis poziciojaba, es hozzaadasa a gameobjects listahoz
				if(movecounter==2){
				AntOdor ao=null;
				ao = (AntOdor) this.game.gameobjectfactory.createGameObject("AntOdor");
				ao.loc_x=this.loc_x;
				ao.loc_y=this.loc_y;
				ao.setOwnerID(ID); //hangyaszag gazdajanak beallitasa
				
				game.gameObjects.add(ao);
				game.view.createAntOdorView(ao);
				movecounter=0;
				}
				ArrayList<Obstacle> obstacles=new ArrayList<Obstacle>(); //kikerulendo akadalyok listaja
				ArrayList<AntLion> lions=new ArrayList<AntLion>(); //hangyalesok listaja
				ArrayList<Food> foods=new ArrayList<Food>(); //kajak listaja
				ArrayList<AntOdor> odors=new ArrayList<AntOdor>(); //szagok listaja
				ArrayList<Ant> ants=new ArrayList<Ant>(); 
				
				//listak feltoltese
				for(MapElement m: game.currentMap.mapelements){
					if(m.getType().equals("lake") || m.getType().equals("Rock"))
						obstacles.add((Obstacle) m);
					if(m.getType().equals("antlion"))
						lions.add((AntLion) m);
					if(m.getType().equals("food"))
						foods.add((Food) m);
				}
				for (GameObject g: game.gameObjects){
					if(g.getType().contains("Odor"))
						odors.add((AntOdor) g);
					else if(g.getType().toLowerCase().contains("ant"))
						ants.add((Ant) g);
				}
				
				//palya szelevel valo utkozes
				if(loc_x<=0){
					turn(90);
					loc_x=11;
				}
				if(loc_y<=0){
					turn(90);
					loc_y=11;
				}
				if(loc_x>=600){
					turn(90);
					loc_x=589;
				}
				if(loc_y>=600){
					turn(90);
					loc_y=589;
				}
				//ha kajaert megy a hangya
				if(!goinghome){
					
				//ha akadallyal utkozunk, akkor 90 fok fordulas jobbra, majd tovabbhaladas
					for(Obstacle o: obstacles){
						if(o.collision(this)){
							turn(270);
							loc_x=(loc_x+dir_x*speed);
							loc_y=(loc_y+dir_y*speed);

							return;
						}
					}
					
					//hangyalesovel valo utkozes ellenorzese
					for(AntLion al: lions){
						if (al.collision(this)){
							return;
						}
					}
					
					//kajaval valo utkoze ellenorzese
					for(Food f: foods){
						f.collision(this);
						
						}
					
					//kajaszagot erez-e a hangya
					for(Food f: foods){
						if(this.loc_x>f.loc_x-f.odor_range && this.loc_x<f.loc_x+f.odor_range && this.loc_y>f.loc_y-f.odor_range && this.loc_y<f.loc_y+f.odor_range){
							//ha igen, akkor az iranyvektorat, ill. a "fokat" afele allitjuk
							double templocx=loc_x-f.loc_x;
							double templocy=loc_y-f.loc_y;
							double lenght=Math.sqrt(templocx*templocx+templocy*templocy);
							templocx/=lenght;
							templocy/=lenght;
							dir_x=templocx;
							dir_y=templocy;
							dir=this.convertDirToAngle(dir_x, dir_y);
							//es elindul a szag fele
							loc_x=loc_x+dir_x*speed*-1;
							loc_y=loc_y+dir_y*speed*-1;
							return;
						}
					}
					AntOdor tempodor= new AntOdor(this.game);
					float odorstrenght=0;
					//erzi-e a hangya mas hangyanak a szagat
					for(AntOdor o: odors){
						if(o.ownerID!=this.ID && o.ownerID!=follower.ID && this.loc_x>o.loc_x-o.range && this.loc_x<o.loc_x+o.range && this.loc_y>o.loc_y-o.range && this.loc_y<o.loc_y+o.range){
							//a legerosebb szag iranyaba forulunk
							if(o.range>odorstrenght && (o.loc_x!=this.anthill.loc_x)&&(o.loc_y!=this.anthill.loc_y)){
								if(o.range>8)break;
								odorstrenght=o.range;
								double templocx=(loc_x-o.loc_x);
								double templocy=(loc_y-o.loc_y);
								double lenght=Math.sqrt(templocx*templocx+templocy*templocy);
								templocx/=lenght;
								templocy/=lenght;
								dir_x=templocx;
								dir_y=templocy;
								dir=this.convertDirToAngle(dir_x, dir_y);
								tempodor=o;
								
							}
						}
					}
	
					//ha ereztunk hangyaszagot akkor afele megyunk
					if(odorstrenght>0){
						for(Ant a: ants){
							if(a.ID==tempodor.ownerID){
								a.follower=this;
							}
						}
						loc_x=loc_x+dir_x*speed*-1;
						loc_y=loc_y+dir_y*speed*-1;
						return;
					}
					
					//ha nem akkkor elore, vagy kis valoszinuseggel elfordulunk
					else{
						
						if(Math.random()>=0.95) turn(20);
						loc_x=loc_x+dir_x*speed;
						loc_y=loc_y+dir_y*speed;
						return;
					}
				
				
				
					}
				
				//ha hazafele megy a hangya
				
				else{
					//ha hazaert, akkor leteszi a kajat es ujra dolgozni indul
					if(this.loc_x>anthill.loc_x-anthill.range && this.loc_x<anthill.loc_x+anthill.range && this.loc_y>anthill.loc_y-anthill.range && this.loc_y<anthill.loc_y+anthill.range)
					{
						foodcarried=0;
						goinghome=false;
						return;
					}
					
					
					
					//ha akadallyal utkozunk, akkor 90 fok fordulas jobbra, majd tovabbhaladas
					for(Obstacle o: obstacles){
						if(o.collision(this)){
							turn(90);
							loc_x=loc_x+dir_x*speed;
							loc_y=loc_y+dir_y*speed;
							return;
						}
					}
					
					//hangyalesovel valo utkozes ellenorzese
					for(AntLion al: lions){
						if(al.collision(this)){
							return;
						}
					}
					
					//hangyaboly fele fodulas es elindulas
					
					double templocx=loc_x-anthill.loc_x;
					double templocy=loc_y-anthill.loc_y;
					double lenght=Math.sqrt(templocx*templocx+templocy*templocy);
					templocx/=lenght;
					templocy/=lenght;
					dir_x=templocx;
					dir_y=templocy;
				    dir=this.convertDirToAngle(dir_x, dir_y);	
				    loc_x=loc_x+dir_x*speed*-1;
					loc_y=loc_y+dir_y*speed*-1;
				    return;
					}
				}
				

						
	
	
	//kaja felvetele
	public void pickupfood(){

		//hangya hatan csokken a hely
		if(this.type.toLowerCase().contains("big"))
				foodcarried+=2;
		else
				foodcarried++;
				//ha tele van a hangya platoja, akkor hazaindul
				if(foodcarried>=capacity)
					goinghome=true;
	}
	
	//hangya megolese
	public void killAnt(){

		//a hangya eltavolitja magat a gameobjects listabol, igy mar semmi sem fog hivatkozni ra
		this.isAlive=false;
		this.game.gameObjects.remove(this);

	}
	
	//hangya iranyanak megvaltoztatasa
	@Override
	public void turn(double deg){
		dir=dir+deg;
		if(dir>=360)dir-=360;
		dir_x=Math.cos((dir*2*Math.PI)/360)*-1;
		dir_y=Math.sin((dir*2*Math.PI)/360)*-1;

	}
	
	//lefujtak-e sprayvel
	public boolean collision(AntKillerSpray p){
		//spray hatosugaraban van-e a hangya
				if(this.loc_x>p.loc_x-p.range && this.loc_x<p.loc_x+p.range && this.loc_y>p.loc_y-p.range && this.loc_y<p.loc_y+p.range){
					//ha igen akkor megoljuk
					return true;
				}
				return false;
			
	}
	
	//utkozott-e a hangyaszsunnel
	public boolean collision(HedgeHog h){
		
				//hanygaszsun "hatosugaraban" van-e a hangya
				if(this.loc_x>h.loc_x-h.range && this.loc_x<h.loc_x+h.range && this.loc_y>h.loc_y-h.range && this.loc_y<h.loc_y+h.range)
				{
					return true;
				}
				return false;
}
	public boolean isGoingHome(){
		return goinghome;
	}
	public boolean getIsAlive(){
		return isAlive;
	}
}